﻿// owner 蒋家伟
#include "Dbg_Warn_Dlg.h"

// qt
#include <QApplication>
#include <QLineEdit>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QPlainTextEdit>
#include <QThread>

// jsdk
#include "IApplication.h"
#include "IApplicationEventArgs.h"

#ifdef _MSC_VER
#include <intrin.h> //__debugbreak头文件
#endif

using namespace jsdk;

namespace
{
    std::wstring getWarnKey(const std::wstring & filePath, const std::wstring & function, const uint32_t rowNumber)
    {
        return filePath + function + std::to_wstring(rowNumber);
    }
}

jsdk::Dbg_Warn_Dlg::Dbg_Warn_Dlg(QWidget *parent) :QDialog(parent)
{
    this->setWindowTitle(QString::fromStdWString(L"异常信息警告"));
    this->setFixedSize(360, 480);
    this->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
    this->setModal(true);
    QVBoxLayout* pMainLayout = new QVBoxLayout;

    // 显示控件的排布
    QFrame* pShowFrame = new QFrame;
    {
        QVBoxLayout* pShowFrameLayout = new QVBoxLayout;
        pShowFrameLayout->addSpacerItem(new QSpacerItem(10, 20, QSizePolicy::Maximum, QSizePolicy::Maximum));
        pShowFrame->setLayout(pShowFrameLayout);

        // 文件路径
        QLabel* pFilePathLabel = new QLabel(QString::fromStdWString(L"文件路径:"));
        m_pFilePathLineEdit = new QPlainTextEdit;
        m_pFilePathLineEdit->setFixedHeight(50);
        m_pFilePathLineEdit->setReadOnly(true);
        QVBoxLayout* pFilePathHBL = new QVBoxLayout;
        pFilePathHBL->addWidget(pFilePathLabel);
        pFilePathHBL->addWidget(m_pFilePathLineEdit);
        pShowFrameLayout->addLayout(pFilePathHBL);

        // 函数名称
        QLabel* pFunctionLabel = new QLabel(QString::fromStdWString(L"函数名称:"));
        m_pFunctionLineEdit = new QPlainTextEdit;
        m_pFunctionLineEdit->setFixedHeight(50);
        m_pFunctionLineEdit->setReadOnly(true);

        QVBoxLayout* pFunctionHBL = new QVBoxLayout;
        pFunctionHBL->addWidget(pFunctionLabel);
        pFunctionHBL->addWidget(m_pFunctionLineEdit);
        pShowFrameLayout->addLayout(pFunctionHBL);

        // 行号
        QLabel* pRowNumberLabel = new QLabel(QString::fromStdWString(L"行号:"));
        m_pRowNumberLineEdit = new QLineEdit;
        m_pRowNumberLineEdit->setReadOnly(true);

        QHBoxLayout* pRowNumberHBL = new QHBoxLayout;
        pRowNumberHBL->addWidget(pRowNumberLabel);
        pRowNumberHBL->addWidget(m_pRowNumberLineEdit);
        pShowFrameLayout->addLayout(pRowNumberHBL);

        // 作者
        QLabel* pOwnerLabel = new QLabel(QString::fromStdWString(L"作者:"));
        m_pOwnerLineEdit = new QLineEdit;
        m_pOwnerLineEdit->setReadOnly(true);

        QHBoxLayout* pOwnerHBL = new QHBoxLayout;
        pOwnerHBL->addWidget(pOwnerLabel);
        pOwnerHBL->addWidget(m_pOwnerLineEdit);
        pShowFrameLayout->addLayout(pOwnerHBL);

        // 时间
        QLabel* pTimeLabel = new QLabel(QString::fromStdWString(L"日期:"));
        m_pTimeLineEdit = new QLineEdit;
        m_pTimeLineEdit->setReadOnly(true);

        QHBoxLayout* pTimeHBL = new QHBoxLayout;
        pTimeHBL->addWidget(pTimeLabel);
        pTimeHBL->addWidget(m_pTimeLineEdit);
        pShowFrameLayout->addLayout(pTimeHBL);

        // 描述
        QLabel* pDescriptionLabel = new QLabel(QString::fromStdWString(L"描述:"));
        m_pDescriptionLineEdit = new QPlainTextEdit;
        m_pDescriptionLineEdit->setReadOnly(true);
        m_pDescriptionLineEdit->setFixedHeight(150); // 定宽
        QVBoxLayout* pDescriptionHBL = new QVBoxLayout;
        pDescriptionHBL->addWidget(pDescriptionLabel);
        pDescriptionHBL->addWidget(m_pDescriptionLineEdit);
        pShowFrameLayout->addLayout(pDescriptionHBL);
    }
    pMainLayout->addWidget(pShowFrame);

    // 控制按钮的排布
    QFrame* pCtrlFrame = new QFrame;
    {
        QHBoxLayout* pCtrlFrameLayout = new QHBoxLayout;
        pCtrlFrame->setLayout(pCtrlFrameLayout);

        // 放置一个空弹簧
        pCtrlFrameLayout->addSpacerItem(new QSpacerItem(200, 10, QSizePolicy::Maximum));

        // 按钮
        m_IgnoredBtn = new QPushButton(QString::fromStdWString(L"忽略一次"));
        connect(m_IgnoredBtn, &QPushButton::pressed, [this]() { this->accept(); });
        pCtrlFrameLayout->addWidget(m_IgnoredBtn);


        m_AlwaysIgnoredBtn = new QPushButton(QString::fromStdWString(L"忽略所有"));
        connect(m_AlwaysIgnoredBtn, &QPushButton::pressed, [this]() {this->setCurrentWarnAlwaysIgnore(); this->accept(); });
        pCtrlFrameLayout->addWidget(m_AlwaysIgnoredBtn);

        m_DebugBtn = new QPushButton(QString::fromStdWString(L"调试"));
        connect(m_DebugBtn, &QPushButton::pressed, [this]() { this->accept();
#ifdef _MSC_VER
        __debugbreak();
#endif
        });
        pCtrlFrameLayout->addWidget(m_DebugBtn);
    }
    pMainLayout->addWidget(pCtrlFrame);
    this->setLayout(pMainLayout);

}

jsdk::OwnerPtr<jsdk::Dbg_Warn_Dlg> jsdk::Dbg_Warn_Dlg::create()
{
    return NEW_AS_OWNERPTR(Dbg_Warn_Dlg);
}

void jsdk::Dbg_Warn_Dlg::show(const std::wstring & filePath, const std::wstring & function, const uint32_t rowNumber, const std::wstring & ownerName, const std::wstring & time, const std::wstring & description)
{
    m_currentWarnKey = getWarnKey(filePath, function, rowNumber);
    if (isAlwaysIgnored(m_currentWarnKey))
    {
        return;
    }

    if (m_pFilePathLineEdit) m_pFilePathLineEdit->setPlainText(QString::fromStdWString(filePath));
    if (m_pFunctionLineEdit) m_pFunctionLineEdit->setPlainText(QString::fromStdWString(function));
    if (m_pRowNumberLineEdit) m_pRowNumberLineEdit->setText(QString::number(rowNumber) + QString::fromStdWString(L"行"));
    if (m_pOwnerLineEdit) m_pOwnerLineEdit->setText(QString::fromStdWString(ownerName));
    if (m_pTimeLineEdit) m_pTimeLineEdit->setText(QString::fromStdWString(time));
    if (m_pDescriptionLineEdit) m_pDescriptionLineEdit->setPlainText(QString::fromStdWString(description));

    this->exec();
}

bool jsdk::Dbg_Warn_Dlg::isAlwaysIgnored(const std::wstring & warnKey) const
{
    const auto& iter = m_warnKeyToIsAlwaysIgnored.find(warnKey);
    if (iter != m_warnKeyToIsAlwaysIgnored.end())
    {
        return iter->second;
    }
    return false;
}

void jsdk::Dbg_Warn_Dlg::setCurrentWarnAlwaysIgnore()
{
    m_warnKeyToIsAlwaysIgnored[m_currentWarnKey] = true;
}
